package com.niiwoo.civet.trade.service.local.auth;

import com.alibaba.dubbo.config.annotation.Reference;
import com.niiwoo.civet.trade.constant.LoanFlowMqConstant;
import com.niiwoo.civet.trade.enums.LoanNodeTypeEnum;
import com.niiwoo.civet.trade.enums.ProjectFlowExecuteRuntimeNodeStatusEnum;
import com.niiwoo.civet.trade.enums.ReturnProjectReasonTypeEnum;
import com.niiwoo.civet.trade.service.local.flowexecute.ProjectFlowExecuteService;
import com.niiwoo.civet.trade.service.local.loan.LoanReturnService;
import com.niiwoo.civet.user.dto.response.DataStatusResponseDTO;
import com.niiwoo.civet.user.enums.UserDataStatusEnum;
import com.niiwoo.civet.user.enums.UserDataTypeEnum;
import com.niiwoo.civet.user.service.UserStatusDubboService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author wping
 * @Description: 信用卡贷授权检查服务类
 * @date 2018/4/24 10:52
 */
@Slf4j
@Service
public class CreditCardLoanAuthCheckService implements AuthCheckService {

    @Reference(version = "1.0.0")
    private UserStatusDubboService userStatusDubboService;

    @Autowired
    private ProjectFlowExecuteService projectFlowExecuteService;

    @Autowired
    private LoanReturnService loanReturnService;

    @Autowired
    private AuthService authService;

    @Autowired
    private SmallLoanAuthCheckService smallLoanAuthCheckService;

    @Override
    public void authCheck(Long flowExecuteId, String userId, Long projectId, int currentExecuteTimes) {

        String methodName = "信用卡贷授权数据检查, flowExecuteId:" + flowExecuteId + ", projectId:" + projectId;
        try {
            // 运营商数据检查
            int operator = smallLoanAuthCheckService.operatorAuthorizeCheckAndUpdate(flowExecuteId, userId, projectId, currentExecuteTimes, SmallLoanAuthCheckService.EXECUTE_TIMES_THRESHOLD);
            // 运营商获取成功返回0, 失败不可重试返回(流程结束)1, 失败但可以重试返回-1
            log.info(methodName + "-运营商检查返回:{}", operator);
            if (1 == operator) {
                return;
            }

            // 信用卡数据检查
            int creditCard = creditCardAuthorizeCheckAndUpdate(flowExecuteId, userId, projectId, currentExecuteTimes, SmallLoanAuthCheckService.EXECUTE_TIMES_THRESHOLD);
            log.info(methodName + "-信用卡检查返回:{}", creditCard);
            if (0 == operator && 0 == creditCard) {
                log.info(methodName + "-运营商、信用卡数据获取成功-当前流程结束, 初始化12项风险规则");
                projectFlowExecuteService.initNextStepProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.AUTH_STATUS_CHECK, LoanNodeTypeEnum.RISK_INFO_HANDLE, LoanFlowMqConstant.Queue.RISK_INFO_HANDLE_QUEUE);
                return;
            }
        } catch (Exception e) {
            log.error(methodName + "-异常", e);
            projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.AUTH_STATUS_CHECK, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, e.getMessage(), currentExecuteTimes);
        }
    }

    /**
     * 信用卡数据检查
     *
     * @param flowExecuteId         借款流程控制ID
     * @param userId                用户ID
     * @param projectId             标的ID
     * @param currentExecuteTimes   当前流程执行次数
     * @param executeTimesThreshold 流程执行次数阈值
     * @return 信用卡获取成功返回0, 失败不可重试返回(流程结束)1, 失败但可以重试返回-1
     */
    public int creditCardAuthorizeCheckAndUpdate(Long flowExecuteId, String userId, Long projectId, int currentExecuteTimes, int executeTimesThreshold) {

        String methodName = "信用卡数据获取检查, flowExecuteId:" + flowExecuteId + ", userId:" + userId + ", projectId:" + projectId;
        DataStatusResponseDTO dataStatusResponseDTO = userStatusDubboService.getByUserIdAndType(userId, UserDataTypeEnum.CREDIT_CARD_AUTHORIZE);
        if (dataStatusResponseDTO == null || dataStatusResponseDTO.getDataStatus() == null) {
            log.info(methodName + "-信用卡授权状态不存在-结束流程, 退回标的");
            authService.failEndProjectFlowExecuteAndReturnProject(flowExecuteId, projectId, ReturnProjectReasonTypeEnum.CREDIT_CARD_FAIL, "信用卡授权状态不存在");
            return 1;
        }

        // 未授权
        if (UserDataStatusEnum.CreditCardStatus.NOCREDIT.getStatus() == dataStatusResponseDTO.getDataStatus().byteValue()) {
            log.info(methodName + "-信用卡授权状态未授权-结束流程, 退回标的");
            authService.failEndProjectFlowExecuteAndReturnProject(flowExecuteId, projectId, ReturnProjectReasonTypeEnum.CREDIT_CARD_FAIL, "信用卡授权状态未授权");
            return 1;
        } else if (UserDataStatusEnum.CreditCardStatus.ALREADY_CREDIT.getStatus() == dataStatusResponseDTO.getDataStatus().byteValue()) {
            // 已授权
            // 判断执行次数
            if (currentExecuteTimes >= executeTimesThreshold) {
                log.info(methodName + "-信用卡数据检查执行次数超过阈值-修改授权状态验证失败(获取数据失败), 结束流程, 退回标的, currentExecuteTimes:{}, executeTimesThreshold:{}", currentExecuteTimes, executeTimesThreshold);
                smallLoanAuthCheckService.updateOperatorStatus(userId, UserDataTypeEnum.CREDIT_CARD_AUTHORIZE, UserDataStatusEnum.CreditCardStatus.GETFAIL.getStatus());
                authService.failEndProjectFlowExecuteAndReturnProject(flowExecuteId, projectId, ReturnProjectReasonTypeEnum.CREDIT_CARD_FAIL, "信用卡数据检查执行次数超过阈值, currentExecuteTimes:" + currentExecuteTimes + ", executeTimesThreshold:" + executeTimesThreshold);
                return 1;
            } else {
                log.info(methodName + "-信用卡已授权且未超数, 继续等待-更新流程状态为异常待重试, authTime:{}", dataStatusResponseDTO.getAuthTime());
                projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.AUTH_STATUS_CHECK, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, "信用卡已授权且未超数", currentExecuteTimes);
                return -1;
            }
        } else if (UserDataStatusEnum.CreditCardStatus.GETSUCCESS.getStatus() == dataStatusResponseDTO.getDataStatus().byteValue()) {
            // 已验证（获取数据）
            log.info(methodName + "-信用卡数据获取成功");
            return 0;
        } else if (UserDataStatusEnum.CreditCardStatus.GETFAIL.getStatus() == dataStatusResponseDTO.getDataStatus().byteValue()) {
            // 验证失败（获取数据失败）
            log.info(methodName + "-信用卡数据验证失败(获取数据失败)-结束流程, 退回标的");
            authService.failEndProjectFlowExecuteAndReturnProject(flowExecuteId, projectId, ReturnProjectReasonTypeEnum.CREDIT_CARD_FAIL, "信用卡数据验证失败(获取数据失败)");
            return 1;
        } else if (UserDataStatusEnum.CreditCardStatus.EXPIRED.getStatus() == dataStatusResponseDTO.getDataStatus().byteValue()) {
            // 验证失败（已过期）
            log.info(methodName + "-信用卡数据已过期-结束流程, 退回标的");
            authService.failEndProjectFlowExecuteAndReturnProject(flowExecuteId, projectId, ReturnProjectReasonTypeEnum.CREDIT_CARD_FAIL, "信用卡数据已过期");
            return 1;
        }
        return -1;
    }
}
